home *** CD-ROM | disk | FTP | other *** search
- Listing 4 - the shape class hierarchy with virtual cloning functions
- employing the relaxed return type rules
-
- #include <iostream.h>
- #include <math.h>
- #include <stddef.h>
-
- //
- // base class 'shape'
- //
- class shape
- {
- public:
- enum palette { BLUE, GREEN, RED };
- shape(palette c);
- virtual double area() const = 0;
- virtual shape *clone() const = 0;
- palette color() const;
- virtual const char *name() const = 0;
- virtual ostream &put(ostream &os) const;
- private:
- palette _color;
- static const char *color_image[RED - BLUE + 1];
- };
-
- const char *shape::color_image[shape::RED - shape::BLUE + 1] =
- { "blue", "green", "red" };
-
- shape::shape(palette c) : _color(c) { }
-
- ostream &shape::put(ostream &os) const
- {
- return os << color_image[color()] << ' ' << name();
- }
-
- shape::palette shape::color() const
- {
- return _color;
- }
-
- //
- // class 'circle' derived from 'shape'
- //
- const double pi = 3.1415926;
-
- class circle : public shape
- {
- public:
- circle(palette c, double r);
- double area() const;
- circle *clone() const;
- const char *name() const;
- ostream &put(ostream &os) const;
- private:
- double radius;
- };
-
- circle::circle(palette c, double r) : shape(c), radius(r) { }
-
- double circle::area() const
- {
- return pi * radius * radius;
- }
-
- const char *circle::name() const
- {
- return "circle";
- }
-
- ostream &circle::put(ostream &os) const
- {
- return shape::put(os) << " with radius = " << radius;
- }
-
- circle *circle::clone() const
- {
- return new circle(*this);
- }
-
- //
- // class 'rectangle' derived from 'shape'
- //
- class rectangle : public shape
- {
- public:
- rectangle(palette c, double h, double w);
- double area() const;
- rectangle *clone() const;
- const char *name() const;
- ostream &put(ostream &os) const;
- private:
- double height, width;
- };
-
- rectangle::rectangle(palette c, double h, double w)
- : shape(c), height(h), width(w) { }
-
- double rectangle::area() const
- {
- return height * width;
- }
-
- const char *rectangle::name() const
- {
- return "rectangle";
- }
-
- ostream &rectangle::put(ostream &os) const
- {
- return shape::put(os) << " with height = " << height
- << " and width = " << width;
- }
-
- rectangle *rectangle::clone() const
- {
- return new rectangle(*this);
- }
-
- //
- // class 'triangle' derived from 'shape'
- //
- class triangle : public shape
- {
- public:
- triangle(palette c, double s1, double s2, double a);
- double area() const;
- triangle *clone() const;
- const char *name() const;
- ostream &put(ostream &os) const;
- private:
- double side1, side2, angle;
- };
-
- triangle::triangle(palette c, double s1, double s2, double a)
- : shape(c), side1(s1), side2(s2), angle(a) { }
-
- double triangle::area() const
- {
- return side1 * sin(angle) * side2 / 2;
- };
-
- const char *triangle::name() const
- {
- return "triangle";
- }
-
- ostream &triangle::put(ostream &os) const
- {
- return shape::put(os) << " with one side = " << side1
- << ", another side = " << side2
- << " and angle = " << angle;
- }
-
- triangle *triangle::clone() const
- {
- return new triangle(*this);
- }
-
- ostream &operator<<(ostream &os, const shape &s)
- {
- return s.put(os);
- }
-